home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / nt / source.exe / POSIX / AR / AR.C next >
C/C++ Source or Header  |  1993-08-25  |  14KB  |  681 lines

  1. /*
  2.       File : ar.c
  3.  
  4.       Author : C S Palkar
  5.  
  6.       Function : Front end for 'ar' to be POSIX complient
  7.  
  8.       Details : The 'ar' command will be invoked it options
  9.                 scaned for validity and an equivalent command
  10.                 constructed for the native archiver, this
  11.                 command is passed to a deamon OR if possible
  12.                 execed.
  13.       Limitations : 
  14.          - Will be unable to replace/update OBJ's in LIB's
  15.            since the capability of LIB is unknow with regard
  16.            to this function.
  17.          - Only one OBJ can be extracted at a time reason same
  18.            as above.
  19.          The solution for the above is to construct a batch file
  20.          which will be executed by the deamon or execed. This
  21.          can be implemented at a latter date.
  22.  
  23.       Date : 22 June 93
  24. */
  25.  
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #include <fcntl.h>
  29. #include <stdlib.h>
  30. #include <stdio.h>
  31. #include <string.h>
  32.  
  33. #define PNULL(p)          (p*)NULL
  34. #define GNULL             PNULL(cmd_cell)
  35. #define SNULL             PNULL(char)
  36.  
  37. #define OPT_TAG           '-'       /* Option tag */
  38. #define EQU               '='       /* EQU */
  39. #define NL                "\n"      /* EOL */
  40. #define OP_CHAR           '/'      /* native opt tag */
  41. #define SP_CHAR           ' '       /* native arg sep */
  42. #define CNULL             '\0'      /* string terminator */
  43.  
  44. #define PT_SEP            "/"      /* Path seperator */
  45. #define CWD               "cwd"     /* Delmiter for path list */
  46.  
  47. #define ST_LIST           "["       /* Trial list start */
  48. #define SP_LIST           "|"       /* Trial list end */
  49. #define ED_LIST           "]"       /* Trial list end */
  50. #define NO_FMTS           2         /* max no of formats */
  51.  
  52. #define DEL_OPT  'd'  /* delete obj */
  53. #define EXT_OPT  'x'  /* extract obj */
  54. #define ADD_OPT  'r'  /* add obj */
  55. #define TAB_OPT  't'  /* tabulate obj */
  56.  
  57. #define VER_OPT  'v'  /* verbose obj */
  58. #define IGN_OPT  'c'  /* Ignore err msg */
  59. #define UPD_OPT  'u'  /* Update archive w.r.t time */
  60.  
  61.  
  62. #define HOST_CC           "lib32"   /* Host 'C' complier */
  63. #define TMP_ENV           "TMP"     /* Env var for tmp dir */
  64. #define TMP_DIR           "/tmp"    /* Default tmp dir */
  65. #define option(a)   ((a) == OPT_TAG )
  66.  
  67. #ifdef DEAMON
  68. #define   D_TMP           "tmp.ar"      /* Input of deamon */
  69. #define   D_IN            "devsem.ini"  /* Input of deamon */
  70. #define   D_OUT           "devsem.out"  /* Output of deamon */
  71. #define   D_ERR           "devsem.err"  /* Error of deamon */
  72. #endif
  73.  
  74. typedef enum { FALSE , TRUE } boolean;
  75. typedef enum { PNUL , DEL , ADD , EXT , TAB } p_flgs;
  76. typedef enum { SNUL , LST , IGN , UPD } s_flgs;
  77.  
  78. typedef struct
  79. {
  80.    char c_opt;
  81.    int  n_ops;
  82.    p_flgs  flgs;
  83.    char *f_str[ NO_FMTS ];
  84. } p_opts;
  85.  
  86. typedef struct
  87. {
  88.    char c_opt;
  89.    p_flgs  flgs;
  90.    char *f_str;
  91. } s_opts;
  92.  
  93. #if DEAMON
  94. typedef struct
  95. {
  96.    char tmp_file[256];
  97.    char out_file[256];
  98.    FILE *de_in;
  99.    FILE *de_out;
  100.    FILE *de_err;
  101. } dm_struct;
  102. #endif
  103.  
  104. typedef struct dummy
  105. {
  106.    struct dummy *nxt;
  107.    char *token;
  108.         boolean optn;
  109. } cmd_cell, *cmd_ptr;
  110.  
  111. /*
  112.     Tables which will help translation
  113. */
  114. p_opts pri_opts[] = {
  115.                       { DEL_OPT , 1 , DEL , { "REMOVE:" , "OUT:" }},
  116.                       { EXT_OPT , 2 , EXT , { "EXTRACT:" , "OUT:" }},
  117.                       { ADD_OPT , 1 , ADD , { SNULL , "OUT:" }},
  118.                       { TAB_OPT , 1 , TAB , { "LIST" , SNULL }},
  119.                       { CNULL   , 0 , PNUL , { SNULL , SNULL }}
  120.                     };
  121.  
  122. s_opts sec_opts[] = { 
  123.                       { VER_OPT , LST , "VERBOSE" },
  124.                       { IGN_OPT , IGN , SNULL  },
  125.                       { UPD_OPT , UPD , SNULL },
  126.                       { CNULL   , SNUL , SNULL }
  127.                     };
  128.  
  129. p_opts *G_ptr;
  130. p_flgs p_flag = PNUL;
  131. int    s_cnt;
  132. s_flgs s_flags[3] = { SNUL , SNUL , SNUL };
  133.  
  134. cmd_cell head_cell , *head_ptr , *end_ptr;
  135.  
  136. /*
  137.  
  138.    Function : print_list()
  139.  
  140.    Discription : Initialise linked list
  141.  
  142.    Called by : main()
  143.  
  144. */
  145.  
  146. void
  147. #ifdef __STDC__
  148. print_list( cmd_ptr ptr , FILE * fp )
  149. #else
  150. print_list( ptr , fp )
  151. cmd_ptr ptr;
  152. FILE *fp;
  153. #endif
  154. {
  155.    cmd_ptr tmp;
  156.    int i;
  157.  
  158.    tmp = ptr;
  159.    
  160.    do
  161.    {
  162.       if ( ptr->optn == TRUE )
  163.       {
  164.          switch ( p_flag )
  165.          {
  166.             case DEL : fputc( OP_CHAR , fp );
  167.                        fputs( G_ptr->f_str[0] , fp );
  168.                        fputs(ptr->token,fp);
  169.                        break;
  170.             case EXT : fputc( OP_CHAR , fp );
  171.                        fputs( G_ptr->f_str[0] , fp );
  172.                        fputs(ptr->token,fp);
  173.                        fputs( NL , fp );
  174.             case ADD : fputc( OP_CHAR , fp );
  175.                        fputs( G_ptr->f_str[1] , fp );
  176.                        fputs(ptr->token,fp);
  177.                        break;
  178.             case TAB : fputc( OP_CHAR , fp );
  179.                        fputs( G_ptr->f_str[0] , fp );
  180.                        fputs( NL , fp );
  181.             default  : fputs(ptr->token,fp);
  182.           }
  183.       }
  184.       else
  185.          fputs(ptr->token,fp);
  186.       fputs( NL , fp );
  187.       ptr = ptr->nxt;
  188.    }
  189.    while ( ptr != tmp );
  190.  
  191.    for ( i = 0 ; i < s_cnt ; i++ )
  192.    {
  193.      if ( s_flags[i] == LST )
  194.      {
  195.          fputc( OP_CHAR , fp );
  196.          fputs( sec_opts->f_str  , fp );
  197.          fputs( NL , fp );
  198.      }
  199.      if ( p_flag == DEL )
  200.      {
  201.          fputc( OP_CHAR , fp );
  202.          fputs( G_ptr->f_str[1] , fp );
  203.          fputs(ptr->nxt->token,fp);
  204.          fputs( NL , fp );
  205.      }
  206.    }
  207. }
  208.  
  209.  
  210. #ifdef DEAMON
  211. /*
  212.        Function : deamon()
  213.  
  214.        Discription : To identify if deamon() is there and open associated
  215.                      files.
  216.  
  217.        Called by : main()
  218. */
  219. dm_struct
  220. #ifdef __STDC__
  221. *deamon(char const *temp_env,
  222.         char const *temp_path,
  223.         char const *de_in,
  224.         char const *de_out,
  225.         char const *de_err,
  226.         char const *de_tmp)
  227. #else
  228. *deamon(temp_env, temp_path, de_in, de_out, de_err,de_tmp)
  229. char const *temp_env;
  230. char const *temp_path;
  231. char const *de_in;
  232. char const *de_out;
  233. char const *de_err;
  234. char const *de_tmp;
  235. #endif
  236. {
  237.    static dm_struct dm_st;
  238.    char *tmp_dir, t_buff[256];
  239.    struct stat s_buff;
  240.    int fd;
  241.  
  242.    if (( tmp_dir = getenv(temp_env)) == ( char * ) NULL )
  243.       return(( dm_struct * ) NULL );
  244.  
  245.    strcpy( t_buff , tmp_dir );
  246.    strcat( strcat ( t_buff , PT_SEP ) , de_in );
  247.    strcpy( dm_st.out_file , t_buff );
  248.  
  249.    while ( stat(t_buff,&s_buff) == 0 )  /* Wait for DEAMON to get free */
  250.      sleep(2);
  251.  
  252.    strcpy( t_buff , tmp_dir );
  253.    strcat( strcat ( t_buff , PT_SEP ) , de_tmp );
  254.    strcpy( dm_st.tmp_file , t_buff );
  255.  
  256.    if (( fd = creat( t_buff , ( mode_t ) 0777 )) != -1 )
  257.    {
  258.       close(fd);
  259.       if (( dm_st.de_in = fopen( t_buff, "w" )) != ( FILE * ) NULL )
  260.          return( &dm_st );
  261.    }
  262.    return(( dm_struct * ) NULL );
  263.  
  264. #if 0
  265.    if (( dm_st.de_in = fopen( t_buff , "w" )) == ( FILE * ) NULL )
  266.       return(( dm_struct * ) NULL );
  267.  
  268.    strcpy( t_buff , tmp_dir );
  269.    strcat( strcat ( t_buff , PT_SEP ) , de_out );
  270.  
  271.    if (( dm_st.de_out = fopen( t_buff , "r" )) == ( FILE * ) NULL )
  272.       return(( dm_struct * ) NULL );
  273.  
  274.    strcpy( t_buff , tmp_dir );
  275.    strcat( strcat ( t_buff , PT_SEP ) , de_err );
  276.  
  277.    if (( dm_st.de_err = fopen( t_buff , "r" )) == ( FILE * ) NULL )
  278.       return(( dm_struct * ) NULL );
  279.  
  280.    return( &dm_st );
  281. #endif
  282. }
  283.  
  284. /*
  285.        Function : disp_deamon()
  286.  
  287.        Discription : To display messages retunred by deamon
  288.  
  289.        Called by : main()
  290. */
  291. int
  292. #ifdef __STDC__
  293. disp_deamon(FILE *fderr)
  294. #else
  295. disp_deamon(fderr)
  296. FILE *fderr;
  297. #endif
  298. {
  299.    return 0;
  300. }
  301.  
  302. /*
  303.        Function : wait_deamon()
  304.  
  305.        Discription : To wait for deamon to finish job
  306.  
  307.        Called by : main()
  308. */
  309. int
  310. #ifdef __STDC__
  311. wait_deamon(char *fdin)
  312. #else
  313. wait_deamon(fdin)
  314. char *fdin;
  315. #endif
  316. {
  317.    FILE *fd;
  318.  
  319.    while ((fd=fopen(fdin,"r")) != ( FILE *) NULL )
  320.    {
  321.       fclose(fd);
  322.       sleep(1);
  323.    }
  324.    return 0;
  325. }
  326.  
  327. /*
  328.        Function : writ_deamon()
  329.  
  330.        Discription : To write to deamon I/P file the new command
  331.  
  332.        Called by : main()
  333. */
  334. int
  335. #ifdef __STDC__
  336. writ_deamon(cmd_cell *head_ptr, FILE *fdout)
  337. #else
  338. writ_deamon(head_ptr, fdout)
  339. cmd_cell *head_ptr;
  340. FILE *fdout;
  341. #endif
  342. {
  343.    char buff[64];
  344.    size_t i;
  345.  
  346.    fprintf(fdout,"%s\n",CWD);
  347.    i = ( size_t ) sizeof( buff );
  348.    if ( getcwd( buff , i ) == CNULL )
  349.       return 0;
  350.    fprintf(fdout,"%s\n",buff);
  351.    print_list( head_ptr , fdout );
  352.    fclose( fdout );
  353.    return 1;
  354. }
  355. #else
  356. /*
  357.        Function : exec_cmd()
  358.  
  359.        Discription : To exec the new command
  360.  
  361.        Called by : main()
  362. */
  363. int
  364. #ifdef __STDC__
  365. exec_cmd(cmd_cell *head_ptr)
  366. #else
  367. exec_cmd(head_ptr)
  368. cmd_cell *head_ptr;
  369. #endif
  370. {
  371.    return 0;
  372. }
  373. #endif
  374.  
  375. /*
  376.        Function : usage()
  377.  
  378.        Discription : To identify if if USAGE of command is correct
  379.  
  380.        Called by : main()
  381. */
  382. int
  383. #ifdef __STDC__
  384. usage(int argc,char *argv)
  385. #else
  386. usage(argc,argv)
  387.    int argc;
  388.    char *argv;
  389. #endif
  390. {
  391.  
  392.    p_opts *p_ptr;
  393.    s_opts *s_ptr;
  394.  
  395.    if ( argc > 1 )
  396.       return 0;
  397.  
  398.    p_ptr = pri_opts;
  399.    s_ptr = sec_opts;
  400.  
  401.    fprintf(stderr,"Useage : %s ",argv);
  402.  
  403.    fputc(OPT_TAG,stderr);
  404.    fputs(ST_LIST,stderr);
  405.  
  406.    while ( p_ptr->c_opt != CNULL )
  407.    {
  408.       fputc(p_ptr->c_opt,stderr);
  409.       p_ptr++;
  410.       if ( p_ptr->c_opt != CNULL )
  411.          fputs(SP_LIST,stderr);
  412.    }
  413.  
  414.    fputs(ED_LIST,stderr);
  415.    fputc(SP_CHAR,stderr);
  416.    fputc(OPT_TAG,stderr);
  417.    fputs(ST_LIST,stderr);
  418.  
  419.    while ( s_ptr->c_opt != CNULL )
  420.    {
  421.       fputc(s_ptr->c_opt,stderr);
  422.       s_ptr++;
  423.    }
  424.  
  425.    fputs(ED_LIST,stderr);
  426.    fputc(SP_CHAR,stderr);
  427.  
  428.    fputs("archive [file(s) .... ]",stderr);
  429.    fputs(NL,stderr);
  430.    return 1;
  431. }
  432.  
  433. /*
  434.  
  435.    Function : init_list()
  436.  
  437.    Discription : Initialise linked list
  438.  
  439.    Called by : main()
  440.  
  441. */
  442.  
  443. cmd_ptr
  444. #ifdef __STDC__
  445. init_list( cmd_ptr cell , char * str )
  446. #else
  447. init_list( cell , str )
  448. cmd_ptr cell;
  449. char *str;
  450. #endif
  451. {
  452.    cell->token = str;
  453.    cell->optn = FALSE;
  454.    cell->nxt = cell;
  455.    end_ptr = cell->nxt;
  456.    return( cell );
  457. }
  458.  
  459. /*
  460.  
  461.    Function : del_list()
  462.  
  463.    Discription : Delete list
  464.  
  465.    Called by : main()
  466.  
  467. */
  468.  
  469. void
  470. #ifdef __STDC__
  471. del_list( cmd_ptr ptr )
  472. #else
  473. del_list( ptr )
  474. cmd_ptr ptr;
  475. #endif
  476. {
  477.    cmd_ptr tmp, tmp2;
  478.  
  479.    if ( ptr == ptr->nxt )
  480.       return;
  481.  
  482.    tmp = ptr;
  483.    ptr = ptr->nxt;
  484.    
  485.    do
  486.    {
  487.       tmp2 = ptr->nxt;
  488.       free( ptr );
  489.       ptr = tmp2;
  490.    }
  491.    while ( ptr != tmp );
  492. }
  493.  
  494.  
  495. /*
  496.  
  497.    Function : new_cell()
  498.  
  499.    Discription : Create new node
  500.  
  501.    Called by : main()
  502.  
  503. */
  504.  
  505. cmd_ptr
  506. #ifdef __STDC__
  507. new_cell( char *str, boolean optn )
  508. #else
  509. new_cell( str , optn )
  510. char *str;
  511. boolean optn;
  512. #endif
  513. {
  514.    cmd_ptr ptr;
  515.  
  516.    if (( ptr = (cmd_ptr)malloc(sizeof(cmd_cell))) == (cmd_ptr) NULL )
  517.       return (( cmd_ptr ) NULL );
  518.    ptr->token = str;
  519.    ptr->optn  = optn;
  520.    return ptr;
  521. }
  522.  
  523. /*
  524.  
  525.    Function : add_list()
  526.  
  527.    Discription : Add at current pos
  528.  
  529.    Called by : main()
  530.  
  531. */
  532.  
  533. cmd_ptr
  534. #ifdef __STDC__
  535. add_list( cmd_ptr ptr , cmd_ptr node )
  536. #else
  537. add_list( ptr , node )
  538. cmd_ptr ptr, node;
  539. #endif
  540. {
  541.    node->nxt = ptr->nxt;
  542.    ptr->nxt = node;
  543.    return node;
  544. }
  545.  
  546. /*
  547.  
  548.    Function : invalid_opts()
  549.  
  550.    Discription : Add at current pos
  551.  
  552.    Called by : main()
  553.  
  554. */
  555.  
  556. int
  557. #ifdef __STDC__
  558. invalid_opts(char *str)
  559. #else
  560. invalid_opts(str)
  561.    char * str;
  562. #endif
  563. {
  564.   p_opts *p_ptr;
  565.   s_opts *s_ptr;
  566.  
  567.   if ( *str == CNULL )
  568.      return 0;
  569.  
  570.   if ( p_flag == PNUL )
  571.   {
  572.      p_ptr = pri_opts;
  573.      while ( p_ptr->c_opt != CNULL )
  574.      {
  575.        if ( p_ptr->c_opt == *str )
  576.        {
  577.           p_flag = p_ptr->flgs;
  578.           G_ptr = p_ptr;
  579.           break;
  580.        }
  581.        else
  582.           p_ptr++;
  583.      }
  584.      if ( p_flag == PNUL )
  585.         return 1;
  586.      str++;
  587.   }
  588.  
  589.   while ( *str != CNULL )
  590.   {
  591.      s_ptr = sec_opts;
  592.      while ( s_ptr->c_opt != CNULL )
  593.      {
  594.        if ( s_ptr->c_opt == *str )
  595.        {
  596.           s_flags[s_cnt++] = s_ptr->flgs;
  597.           break;
  598.        }
  599.        else
  600.           s_ptr++;
  601.      }
  602.      if ( s_ptr->c_opt == CNULL && !s_cnt )
  603.        return 1;
  604.      str++;
  605.    }
  606.    return 0;
  607. }
  608. /*----------------------------------------------------------------------*/
  609. int
  610. #ifdef __STDC__
  611. main(int argc, char **argv)
  612. #else
  613. main(argc,argv)
  614.    int argc;
  615.    char ** argv;
  616. #endif
  617. {
  618. #ifdef DEAMON
  619.    dm_struct *dm_ptr;
  620. #endif
  621.    cmd_ptr tmp_ptr;
  622.    boolean bull;
  623.    int i;
  624.  
  625.    if ( usage(argc,argv[0]))
  626.       return 0;
  627.    i = 1;
  628.    while ( i < argc && option(*argv[i]))
  629.      if ( invalid_opts(argv[i]+1))
  630.         return usage(1,argv[0]);
  631.      else
  632.         i++;
  633.         
  634. #if DEAMON
  635.    if((dm_ptr=deamon(TMP_ENV,TMP_DIR,D_IN,D_OUT,D_ERR,D_TMP))==(dm_struct*)NULL)
  636.    {
  637.       fprintf(stderr,"Cannot execute %s deamon missing\n",*argv[0]);
  638.       return 0;
  639.    }
  640. #endif
  641.  
  642.    head_ptr = init_list( &head_cell , HOST_CC );
  643.    
  644.    bull = p_flag == ADD || p_flag == TAB;
  645.    if (( tmp_ptr = new_cell( argv[i] , bull )) == GNULL )
  646.    {
  647.        fprintf(stderr,"ERROR:Not enough memory.\n");
  648.        return 0;
  649.    }
  650.   
  651.    end_ptr = add_list ( end_ptr , tmp_ptr );
  652.    i++;
  653.    bull = p_flag == DEL || p_flag == EXT;
  654.  
  655.    while ( i < argc )
  656.    {
  657.       if (( tmp_ptr = new_cell( argv[i] , bull )) == GNULL )
  658.       {
  659.           fprintf(stderr,"ERROR:Not enough memory.\n");
  660.           return 0;
  661.       }
  662.       end_ptr = add_list ( end_ptr , tmp_ptr );
  663.       i++;
  664.    }
  665.  
  666. #if DEAMON
  667.    if ( !writ_deamon( head_ptr , dm_ptr->de_in ))
  668.    {
  669.       fprintf(stderr,"Unable to communicate with DEAMON. EXITING!\n");
  670.       return 0;
  671.    }
  672.    rename( dm_ptr->tmp_file, dm_ptr->out_file );
  673.    wait_deamon( dm_ptr->out_file );
  674.    disp_deamon( dm_ptr->de_err );
  675. #else
  676.    exec_cmd( head_ptr );
  677. #endif
  678.    del_list( head_ptr );
  679.    return 0;
  680. }
  681.